package com.xbh.management.filter;

import cn.hutool.core.util.ObjectUtil;
import com.nimbusds.jose.JOSEException;
import com.xbh.common.utils.JwtUtil;
import com.xbh.common.utils.RedisUtils;
import com.xbh.common.web.core.Result;
import com.xbh.management.exception.JwtSignatureVerifyException;
import com.xbh.management.utils.JwtUtilManagement;
import com.xbh.management.utils.ResponseUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * @program: management-center
 * @description: 授权
 * @author: 许宝华
 * @create: 2021-10-05 16:24
 */

/**
 * 处理HTTP请求中的BASIC authorization头部，把认证结果写入SecurityContextHolder。
 * 当一个HTTP请求中包含一个名字为Authorization的头部，并且其值格式是Basic xxx时，
 * 该Filter会认为这是一个BASIC authorization头部

 */
public class TokenAuthFilter extends BasicAuthenticationFilter {


    private static Logger log = LoggerFactory.getLogger(TokenAuthFilter.class);


    private JwtUtilManagement jwtUtilManagement;

    private RedisUtils redisUtils;

    public TokenAuthFilter(AuthenticationManager authenticationManager, JwtUtilManagement jwtUtilManagement, RedisUtils redisUtils) {
        super(authenticationManager);
        this.jwtUtilManagement = jwtUtilManagement;
        this.redisUtils = redisUtils;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        log.info("已认证成功，开始授权");
        //获取当前认证成功用户权限信息
        UsernamePasswordAuthenticationToken authRequest=getAuthentication(request);
        if(authRequest != null){
            log.info("authRequest==========="+authRequest.toString());
            SecurityContextHolder.getContext().setAuthentication(authRequest);
        }
        if(ObjectUtil.isEmpty(authRequest)){
            ResponseUtil.out(response, Result.result("1000","token已过期，请重新登录",null));
        }

        chain.doFilter(request,response);

    }

    private  UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request){
        String token = request.getHeader("Authorization");
        //判断token是否过期
        if(!redisUtils.exists("token_"+ JwtUtil.getUsername())){
            return null;
        }
        if(token != null){
            log.info("token========"+token);
            //获取用户名
            String username = JwtUtil.getUsername();
            log.info(username);
            //获取该用户所拥有的菜单信息
            List<String> permissionValueList = (List<String>) redisUtils.get(username);
            if(permissionValueList.isEmpty()){
                return null;
            }
            Collection<GrantedAuthority> authorities=new ArrayList<>();
            for (String permissionValue : permissionValueList) {
                SimpleGrantedAuthority auth=new SimpleGrantedAuthority(permissionValue);
                authorities.add(auth);
            }
            return new UsernamePasswordAuthenticationToken(username,token,authorities);

        }
        return null;
    }
}
